using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Xml;
using System.Web;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
using System.Web.Hosting;


namespace Thinxoft.HttpLib
{
	/// <summary>
	/// Summary description for HttpRequest.
	/// </summary>
	public class HttpRequest : MarshalByRefObject, IHttpRequest
	{
		
	
        NameValueCollection httpHeaders = new NameValueCollection();
        string method, httpVersion;
		HttpResource resource;
        NameValueCollection getParams, postParams;
        HttpApplicationCollection apps;
		HttpCookies cookies;
        HttpApplication app;







        public HttpRequest(ref byte[] request, HttpApplicationCollection apps,ref NameValueCollection headers,ref NameValueCollection postparams)
        {
            getParams = new NameValueCollection();
            if (postparams != null)
                postParams = postparams;
            else
                postparams = new NameValueCollection();
           
            this.httpHeaders = headers;
            this.method = httpHeaders["method"];
            this.httpVersion = httpHeaders["HttpVersion"];
            this.resource = new HttpResource(httpHeaders["resource"], this.apps);
            this.app = resource.ServerInfo;

        }

        public HttpRequest(ref NameValueCollection headers,ref NameValueCollection postparams,ref HttpResource resource)
        {
            getParams = new NameValueCollection();
            if (postparams != null)
                postParams = postparams;
            else
                postparams = new NameValueCollection();
           
            this.httpHeaders = headers;
            this.method = httpHeaders["method"];
            this.httpVersion = httpHeaders["HttpVersion"];
            this.resource = resource;
            this.app = resource.ServerInfo;

        }


		#region [properties]

		

		public string Method
		{
			get
			{
				return this.method;
			}
		}

		public HttpResource Resource
		{
			get
			{
				return this.resource;
			}
		}

		public IHttpResource RequestResource
		{
			get
			{
				return this.resource;
			}
		}

		public string HTTPVersion
		{
			get
			{
				return this.httpVersion;
			}
		}

		public int ContentLength
		{
			get
			{
				return int.Parse((string)this.httpHeaders["content-length"]);
			}
		}

        public NameValueCollection Form
        {
			get
			{
				return this.postParams;
			}
		}

        public NameValueCollection QueryString
        {
			get
			{
				return this.getParams;
			}
		}

		public HttpCookies  Cookies
		{
			get
			{
				return this.cookies;
			}
		}

		public IHttpCookies RequestCookies
		{
			get
			{
				return this.cookies;
			}
		}
		

		public string this[string name]
		{
			get
			{
				foreach(string key in this.Form.AllKeys)
				{
					if(key.ToLower() == name.ToLower())
					{
						return this.Form[name];
					}
				}

				foreach(string key in this.QueryString.AllKeys)
				{
					if(key.ToLower() == name.ToLower())
					{
						return HttpUtility.UrlDecode(this.QueryString[name]);
					}
				}
				return null;
			}
		}
		#endregion


        public void ProcessRequest(string query)
		{			
			if(query.Length  > 0)
			{
				string[] parameters = query.Split("&".ToCharArray());
				foreach(string parameter in parameters)
				{
					string[] nameVal  = parameter.Split("=".ToCharArray());
					string name = nameVal[0].Remove(0,1);
					getParams.Add(name,nameVal[1]);
				}
               
			}

            LoadCookies();
        }

		void LoadCookies()
		{
			if(httpHeaders["cookie"] != null)
			{
				string c = httpHeaders["cookie"].ToLower();
				string[] cks = c.Split(" ".ToCharArray());
				this.cookies = new HttpCookies(cks);
			}else
				this.cookies = new HttpCookies();
		}

        public HttpResponse CreateResponse()
        {
            if (resource.Exists)
            {
                if (resource.IsXFile)
                {
                    if (!cookies.HasCookie("session"))
                    {
                        string sessionId = Guid.NewGuid().ToString();
                        this.cookies.Add("session", sessionId);
                        this.app.CreateSession(sessionId);
                    }

                    Interpreter i = new Interpreter(ref this.resource,this);
                    HttpResponse resp = i.Interprete();
                    return resp;

                }
                else if (resource.IsASPXFile)
                {

                    return null;
                }
                else
                {
                    return new HttpResponse(this.resource, "200 OK", "", app);
                }
            }
            else
            {
                return new HttpResponse("Could not find the specified file", "200 OK", app);
            }

        }

		

	}
}
